#include "/home/zzzzz/temu/temu/include/cpu/reg.h"
#include "watchpoint.h"
#include "expr.h"

#define NR_WP 32

WP wp_pool[NR_WP];
WP *head, *free_;
extern CPU_state cpu;
extern int wp_init;
void init_wp_pool() {
	int i;
	for(i = 0; i < NR_WP; i ++) {
		wp_pool[i].NO = i;
		wp_pool[i].next = &wp_pool[i + 1];
	}
	wp_pool[NR_WP - 1].next = NULL;

	head = NULL;
	free_ = wp_pool;

	wp_init = 1;
}

/* TODO: Implement the functionality of watchpoint */



WP* new_wp(){
	WP *q,*p;
	q = free_;
	free_ = free_->next;
	q->next = NULL;
	p =  head;
	if(p == NULL){
		head = q;
		p = head;
	}
	else
	{
		while(p->next != NULL )
			p = p->next;
		p->next = q;
	}
	return q;
}

void free_wp(WP* op){
	WP *q,*p;
	p = free_;
	if(p == NULL){
		free_ = op;
		p = free_;
	}
	else
	{
		while( p->next != NULL)
			p = p->next;
		p->next = op;
	}
	q = head;
	if(head == NULL)
		assert(0);
	if(head->NO == op->NO)
		head = head->next;
	else
	{
		while (q->next != NULL && q->next->NO != op->NO)
			q = q->next;
		if (q->next == NULL && q->NO == op->NO)
			printf ("what ghost!");
		else if (q->next->NO == op->NO)
			q->next = q->next->next;
		else
			assert (0);
	}
	op->next = NULL;
	op->val = 0;
	op->b = 0;
	op->str[0] = '\0';
}

void info_wp()
{
	WP *p;
	p=head;
	while (p != NULL)
	{
		printf ("Watchpoint %d: %s = %d\n",p->NO,p->str,p->val);
		p = p->next;
	}
}

void delete_wp(int num)
{
	WP *p;
	p = &wp_pool[num];
	free_wp (p);
}

bool check_wp()
{
	WP *p;
	p = head;
	bool flag = 1,tmp;
	while( p != NULL)
	{
		uint32_t num = expr(p->str,&tmp);
		if(!tmp)
			assert(1);
		if(num != p->val){
			flag = false;
			if(p->b)
			{
				printf("Hit breakpoint %d at 0x%08x\n",p->b,cpu.pc);
				p = p->next;
				continue;
			}
			printf("Watchpoint %d: %s\nNew value = %d\n",p->NO,p->str,num);
			p->val = num;
		}
		p = p->next;
	}
	return flag;
}

